package com.spring.lo.framework.factory.xml.parser;

import com.mysql.cj.util.StringUtils;
import com.spring.lo.framework.factory.config.BeanDefinition;
import com.spring.lo.framework.factory.config.PropertyValue;
import com.spring.lo.framework.factory.config.RuntimeBeanReference;
import com.spring.lo.framework.factory.config.TypedStringValue;
import com.spring.lo.framework.util.ReflectionUtils;
import org.dom4j.Element;

import java.util.List;

/**
 * BeanDefinition解析的代理类
 * 负责：1.默认标签转换BeanDefinition；2.其他标签进行分发（未实现）
 * @author zhangbh
 * 2023-05-29 08:12
 **/
public class BeanDefinitionParserDelegate {

    private final static String DEFAULT_BEANS = "beans";
    private final static String DEFAULT_BEAN = "bean";

    public boolean isDefaultNamespace(Element element) {
        String name = element.getName();
        return name.equals(DEFAULT_BEANS)
                || name.equals(DEFAULT_BEAN);
    }

    /**
     * 解析默认命名空间的标签为BeanDefinition
     * @param element <bean></bean>标签
     * @return BeanDefinition
     */
    public BeanDefinition parseDefaultBeanDefinition(Element element) {
        // 设置普通属性 id name scope init-method
        String clazz = element.attributeValue("class");
        if (StringUtils.isNullOrEmpty(clazz)) {
            System.out.println("!!!!!元素class为空，跳过加载!!!!");
            return null;
        }
        String id = element.attributeValue("id");
        if (StringUtils.isNullOrEmpty(id)) {
            System.out.println("!!!!!元素id为空，跳过加载!!!!");
            return null;
        }

        BeanDefinition bd = new BeanDefinition(id, clazz);
        String scope = element.attributeValue("scope");
        if (StringUtils.isNullOrEmpty(scope)) {
            scope = "singleton";
        }
        bd.setScope(scope);
        String name = element.attributeValue("name");
        if (StringUtils.isNullOrEmpty(name)) {
            name = id;
        }
        bd.setBeanName(name);
        String initMethod = element.attributeValue("init-method");
        bd.setInitMethod(initMethod);
        // 设置属性 properties
        parseProperties(bd, element);
        return bd;
    }

    public BeanDefinition parseCustomBeanDefinition(Element element) {
        // todo 如果后期要扩展自定义标签解析，就是在这边
        return null;
    }

    private void parseProperties(BeanDefinition bd, Element element) {
        List<Element> propertyList = element.elements("property");
        Class<?> classType = bd.getClassType();
        for (Element property : propertyList) {
            String name = property.attributeValue("name");
            if (StringUtils.isNullOrEmpty(name)) {
                continue;
            }
            String value = property.attributeValue("value");
            String ref = property.attributeValue("ref");
            if (StringUtils.isNullOrEmpty(value) && StringUtils.isNullOrEmpty(ref)) {
                System.out.println(name + "属性的值为空!!!!!");
                continue;
            }
            PropertyValue pv = null;
            if (StringUtils.isNullOrEmpty(value)) {
                // 加载引用值
                RuntimeBeanReference reference = new RuntimeBeanReference(ref);
                pv = new PropertyValue(name, reference);
            } else {
                // 加载普通值
                // 通过属性名获取实际类型
                Class<?> fieldType = ReflectionUtils.getFieldType(classType, name);
                if (fieldType == null) {
                    continue;
                }
                TypedStringValue realValue = new TypedStringValue(value, fieldType);
                pv = new PropertyValue(name, realValue);
            }
            bd.addPropertyValue(pv);
        }
    }
}
